#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <stdexcept>
#include <cctype>
#include <memory>

// 令牌类型
enum class TokenType {
    IDENTIFIER,      // Window, Row, Rectangle, qsTr 等
    STRING,         // "Blue", "test"
    NUMBER,         // 640, 480, 0.15
    LBRACE,         // {
    RBRACE,         // }
    COLON,          // :
    DOT,            // .
    MULTIPLY,       // *
    LPAREN,         // (
    RPAREN,         // )
    IMPORT,         // import
    TRUE,           // true
    FALSE,          // false
    EOF_TOKEN
};

// 令牌结构
struct Token {
    TokenType type;
    std::string value;

    Token(TokenType t, std::string v) : type(t), value(v) {}
};

// 词法分析器
class Lexer {
private:
    std::string text;
    size_t pos;

    void skip_whitespace() {
        while (pos < text.length() && std::isspace(text[pos])) {
            pos++;
        }
    }

public:
    Lexer(const std::string& input) : text(input), pos(0) {}

    std::vector<Token> tokenize() {
        std::vector<Token> tokens;

        while (pos < text.length()) {
            skip_whitespace();
            if (pos >= text.length()) break;

            char current = text[pos];

            // 标识符
            if (std::isalpha(current)) {
                std::string identifier;
                while (pos < text.length() && (std::isalnum(text[pos]) || text[pos] == '_')) {
                    identifier += text[pos++];
                }
                if (identifier == "import") {
                    tokens.emplace_back(TokenType::IMPORT, identifier);
                } else if (identifier == "true") {
                    tokens.emplace_back(TokenType::TRUE, identifier);
                } else if (identifier == "false") {
                    tokens.emplace_back(TokenType::FALSE, identifier);
                } else {
                    tokens.emplace_back(TokenType::IDENTIFIER, identifier);
                }
                continue;
            }

            // 数字（支持浮点数，如 2.15, 0.15）
            if (std::isdigit(current)) {
                std::string number;
                number += current;
                pos++;
                bool has_dot = false;
                while (pos < text.length() && (std::isdigit(text[pos]) || text[pos] == '.')) {
                    if (text[pos] == '.') {
                        if (has_dot) {
                            throw std::runtime_error("Invalid number format at position " + std::to_string(pos));
                        }
                        has_dot = true;
                    }
                    number += text[pos++];
                }
                tokens.emplace_back(TokenType::NUMBER, number);
                continue;
            }

            // 单独的小数点开头的数字（如 .15）
            if (current == '.' && pos + 1 < text.length() && std::isdigit(text[pos + 1])) {
                std::string number = "0";
                number += current;
                pos++;
                // bool has_dot = true;
                while (pos < text.length() && std::isdigit(text[pos])) {
                    number += text[pos++];
                }
                tokens.emplace_back(TokenType::NUMBER, number);
                continue;
            }

            // 字符串
            if (current == '"') {
                pos++;
                std::string str;
                while (pos < text.length() && text[pos] != '"') {
                    str += text[pos++];
                }
                if (pos >= text.length()) {
                    throw std::runtime_error("Unterminated string at position " + std::to_string(pos));
                }
                pos++;
                tokens.emplace_back(TokenType::STRING, str);
                continue;
            }

            // 符号
            if (current == '{') {
                tokens.emplace_back(TokenType::LBRACE, "{");
            } else if (current == '}') {
                tokens.emplace_back(TokenType::RBRACE, "}");
            } else if (current == ':') {
                tokens.emplace_back(TokenType::COLON, ":");
            } else if (current == '.') {
                tokens.emplace_back(TokenType::DOT, ".");
            } else if (current == '*') {
                tokens.emplace_back(TokenType::MULTIPLY, "*");
            } else if (current == '(') {
                tokens.emplace_back(TokenType::LPAREN, "(");
            } else if (current == ')') {
                tokens.emplace_back(TokenType::RPAREN, ")");
            } else {
                throw std::runtime_error("Unexpected character: " + std::string(1, current) + " at position " + std::to_string(pos));
            }

            pos++;
        }

        tokens.emplace_back(TokenType::EOF_TOKEN, "");
        return tokens;
    }
};

// AST 节点基类（用于 JavaScript 表达式）
class ExprNode {
public:
    virtual ~ExprNode() = default;
    virtual double evaluate(const std::unordered_map<std::string, double>& context) const = 0;
};

// 数字节点
class NumberExprNode : public ExprNode {
private:
    double value;

public:
    NumberExprNode(double v) : value(v) {}
    double evaluate(const std::unordered_map<std::string, double>&) const override {
        return value;
    }
};

// 属性访问节点（如 parent.width）
class PropertyExprNode : public ExprNode {
private:
    std::string object;
    std::string property;

public:
    PropertyExprNode(std::string obj, std::string prop) : object(obj), property(prop) {}
    double evaluate(const std::unordered_map<std::string, double>& context) const override {
        std::string key = object + "." + property;
        auto it = context.find(key);
        if (it == context.end()) {
            throw std::runtime_error("Undefined property: " + key);
        }
        return it->second;
    }
};

// 二元运算节点（如 parent.height * 0.15）
class BinOpExprNode : public ExprNode {
private:
    Token op;
    std::unique_ptr<ExprNode> left;
    std::unique_ptr<ExprNode> right;

public:
    BinOpExprNode(Token o, std::unique_ptr<ExprNode> l, std::unique_ptr<ExprNode> r)
        : op(o), left(std::move(l)), right(std::move(r)) {}

    double evaluate(const std::unordered_map<std::string, double>& context) const override {
        double l = left->evaluate(context);
        double r = right->evaluate(context);
        if (op.type == TokenType::MULTIPLY) {
            return l * r;
        }
        throw std::runtime_error("Unknown operator: " + op.value);
    }
};

// QML 属性
struct Property {
    std::string name;
    std::unique_ptr<ExprNode> value; // 数字或表达式
    std::string string_value;        // 字符串值（如 "Blue"）
    bool bool_value;                 // 布尔值（如 true）
    bool is_bool;                    // 是否为布尔值

    Property(std::string n, std::unique_ptr<ExprNode> v) : name(n), value(std::move(v)), is_bool(false) {}
    Property(std::string n, std::string sv) : name(n), string_value(sv), is_bool(false) {}
    Property(std::string n, bool bv) : name(n), bool_value(bv), is_bool(true) {}
};

// QML 组件
struct Component {
    std::string type;
    std::vector<Property> properties;
    std::vector<std::unique_ptr<Component>> children;

    Component(std::string t) : type(t) {}
};

// 语法分析器
class Parser {
private:
    std::vector<Token> tokens;
    size_t pos;

    const Token& current_token() const {
        return tokens[pos];
    }

    void eat(TokenType type) {
        if (current_token().type == type) {
            pos++;
        } else {
            throw std::runtime_error("Expected token " + std::to_string(static_cast<int>(type)) +
                                     " (" + token_type_to_string(type) +
                                     "), got " + std::to_string(static_cast<int>(current_token().type)) +
                                     " (" + token_type_to_string(current_token().type) + ") at value: " + current_token().value);
        }
    }

    std::string token_type_to_string(TokenType type) const {
        switch (type) {
            case TokenType::IDENTIFIER: return "IDENTIFIER";
            case TokenType::STRING: return "STRING";
            case TokenType::NUMBER: return "NUMBER";
            case TokenType::LBRACE: return "LBRACE";
            case TokenType::RBRACE: return "RBRACE";
            case TokenType::COLON: return "COLON";
            case TokenType::DOT: return "DOT";
            case TokenType::MULTIPLY: return "MULTIPLY";
            case TokenType::LPAREN: return "LPAREN";
            case TokenType::RPAREN: return "RPAREN";
            case TokenType::IMPORT: return "IMPORT";
            case TokenType::TRUE: return "TRUE";
            case TokenType::FALSE: return "FALSE";
            case TokenType::EOF_TOKEN: return "EOF_TOKEN";
            default: return "UNKNOWN";
        }
    }

    std::unique_ptr<ExprNode> factor() {
        const Token& token = current_token();
        if (token.type == TokenType::NUMBER) {
            eat(TokenType::NUMBER);
            return std::make_unique<NumberExprNode>(std::stod(token.value));
        } else if (token.type == TokenType::IDENTIFIER) {
            std::string obj = token.value;
            eat(TokenType::IDENTIFIER);
            if (current_token().type == TokenType::DOT) {
                eat(TokenType::DOT);
                std::string prop = current_token().value;
                eat(TokenType::IDENTIFIER);
                return std::make_unique<PropertyExprNode>(obj, prop);
            }
            // 如果没有 .，可能是单独的标识符（暂不支持）
            throw std::runtime_error("Expected '.' after identifier: " + obj);
        }
        throw std::runtime_error("Expected number or identifier, got: " + token.value);
    }

    std::unique_ptr<ExprNode> expr() {
        auto node = factor();
        while (current_token().type == TokenType::MULTIPLY) {
            Token op = current_token();
            eat(TokenType::MULTIPLY);
            node = std::make_unique<BinOpExprNode>(op, std::move(node), factor());
        }
        return node;
    }

    Property property() {
        std::string name = current_token().value;
        eat(TokenType::IDENTIFIER);
        eat(TokenType::COLON);
        if (current_token().type == TokenType::STRING) {
            std::string value = current_token().value;
            eat(TokenType::STRING);
            return Property(name, value);
        } else if (current_token().type == TokenType::TRUE) {
            eat(TokenType::TRUE);
            return Property(name, true);
        } else if (current_token().type == TokenType::FALSE) {
            eat(TokenType::FALSE);
            return Property(name, false);
        } else if (current_token().type == TokenType::IDENTIFIER && pos + 1 < tokens.size() && tokens[pos + 1].type == TokenType::LPAREN) {
            eat(TokenType::IDENTIFIER); // qsTr
            eat(TokenType::LPAREN);
            std::string value = current_token().value;
            eat(TokenType::STRING);
            eat(TokenType::RPAREN);
            return Property(name, value); // 简化处理 qsTr("test")
        } else {
            return Property(name, expr());
        }
    }

    std::unique_ptr<Component> component() {
        std::string type = current_token().value;
        eat(TokenType::IDENTIFIER);
        eat(TokenType::LBRACE);
        auto comp = std::make_unique<Component>(type);

        while (current_token().type != TokenType::RBRACE && current_token().type != TokenType::EOF_TOKEN) {
            if (current_token().type == TokenType::IDENTIFIER && pos + 1 < tokens.size() && tokens[pos + 1].type == TokenType::LBRACE) {
                comp->children.push_back(component());
            } else {
                comp->properties.push_back(property());
            }
        }

        eat(TokenType::RBRACE);
        return comp;
    }

    void parse_import() {
        eat(TokenType::IMPORT);
        eat(TokenType::IDENTIFIER);
        if (current_token().type == TokenType::NUMBER) {
            eat(TokenType::NUMBER); // 解析版本号如 2.15
        } else if (current_token().type == TokenType::IDENTIFIER) {
            eat(TokenType::IDENTIFIER); // 解析如 QtQuick.Controls
        }
    }

public:
    Parser(const std::vector<Token>& t) : tokens(t), pos(0) {}

    std::vector<std::unique_ptr<Component>> parse() {
        std::vector<std::unique_ptr<Component>> components;
        while (current_token().type != TokenType::EOF_TOKEN) {
            if (current_token().type == TokenType::IMPORT) {
                parse_import();
            } else {
                components.push_back(component());
            }
        }
        return components;
    }
};

// 解释器
class Interpreter {
private:
    std::unordered_map<std::string, double> context;

    void print_component(const Component& comp, int indent = 0) {
        std::string indent_str(indent * 2, ' ');
        std::cout << indent_str << "Component: " << comp.type << "\n";
        for (const auto& prop : comp.properties) {
            std::cout << indent_str << "  Property: " << prop.name << " = ";
            if (!prop.string_value.empty()) {
                std::cout << "\"" << prop.string_value << "\"";
            } else if (prop.is_bool) {
                std::cout << (prop.bool_value ? "true" : "false");
            } else if (prop.value) {
                try {
                    std::cout << prop.value->evaluate(context);
                } catch (const std::exception& e) {
                    std::cout << "[Error: " << e.what() << "]";
                }
            }
            std::cout << "\n";
        }
        for (const auto& child : comp.children) {
            // 更新上下文，模拟 parent 属性
            if (comp.type == "Window" || comp.type == "Row") {
                for (const auto& p : comp.properties) {
                    if (p.name == "width" && p.value) context["parent.width"] = p.value->evaluate(context);
                    if (p.name == "height" && p.value) context["parent.height"] = p.value->evaluate(context);
                }
            }
            print_component(*child, indent + 1);
        }
    }

public:
    void interpret(const std::vector<std::unique_ptr<Component>>& components) {
        // 初始化上下文
        context["parent.width"] = 640.0;
        context["parent.height"] = 480.0;

        for (const auto& comp : components) {
            print_component(*comp);
        }
    }
};



static std::string token_type_to_string(TokenType type) {
    switch (type) {
        case TokenType::IDENTIFIER: return "IDENTIFIER";
        case TokenType::STRING: return "STRING";
        case TokenType::NUMBER: return "NUMBER";
        case TokenType::LBRACE: return "LBRACE";
        case TokenType::RBRACE: return "RBRACE";
        case TokenType::COLON: return "COLON";
        case TokenType::DOT: return "DOT";
        case TokenType::MULTIPLY: return "MULTIPLY";
        case TokenType::LPAREN: return "LPAREN";
        case TokenType::RPAREN: return "RPAREN";
        case TokenType::IMPORT: return "IMPORT";
        case TokenType::TRUE: return "TRUE";
        case TokenType::FALSE: return "FALSE";
        case TokenType::EOF_TOKEN: return "EOF_TOKEN";
        default: return "UNKNOWN";
    }
}

// 主函数
int main() {
    std::string qml_code = R"(
        import QtQuick 2.15
        import QtQuick.Controls
        Window {
            width: 640
            height: 480
            visible: true
            title: qsTr("test")
            Row {
                height: parent.height
                width: parent.width
                Rectangle {
                    color: "Blue"
                    height: parent.height * 0.15
                    width: parent.width
                }
            }
        }
    )";

    try {
        Lexer lexer(qml_code);
        auto tokens = lexer.tokenize();
        // 调试：打印所有令牌
        for (const auto& token : tokens) {
            std::cout << "Token: " << static_cast<int>(token.type) << " (" << 
                         token_type_to_string(token.type) << "), Value: " << token.value << "\n";
        }
        Parser parser(tokens);
        auto components = parser.parse();
        Interpreter interpreter;
        interpreter.interpret(components);
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

    return 0;

}